package com.audaque.springboot.foshanupload.web.webdemo.anno;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**自定义注解*/
/*元注解：在定义注解的时候用来贴在注解上的注解，用来限定注解的用法
元注解有4个：
    @Retention、@Target、@Documented、@Inherited*/
@Target(
		{
			ElementType.ANNOTATION_TYPE, //贴在注解上(元注解)
			ElementType.CONSTRUCTOR, //贴在构造方法上
			ElementType.FIELD, //(注意)贴在字段上（包括枚举常量）
			ElementType.LOCAL_VARIABLE , // 贴在局部变量上
			ElementType.METHOD, //(注意)贴在方法上
			ElementType.PACKAGE , //  贴在包上（极少使用）
			ElementType.PARAMETER, // 贴在参数上
			ElementType.TYPE//(注意)贴在类、接口或枚举上
		}
	   )
@Retention(
		//RetentionPolicy.SOURCE：    表示注解只存在于源文件中，不会被编译到字节码中
		//RetentionPolicy.CLASS：       表示注解会被编译到字节码中，但是JVM不加载注解
		RetentionPolicy.RUNTIME//： 表示注解会被编译到字节中，会随着字节码的加载而进入JVM,因此可以反射性地读取
		/*我们开发中的自定义的注解的有效期都要使用RUNTIME，这样才能在程序运行时使用反射赋予注解功能
		反编译演示有些注解不会被编译到字节码中*/
)
@Inherited    //表示注解会遗传给子类
@Documented	   // 表示注解会被javadoc指令编辑到API中
//@interface表示特殊的接口
public @interface  CustomAnnotations {
	//定义属性—>定义抽象方法：默认publicabstract，可以像接口一样被继承或者被实现
	//注意：属性的返回值类型只能是基本类型/枚举/Class/注解/String/枚举以及他们各自的数组
	int value();
/*注意：1.给属性赋值时如果只有1个属性要赋值且名称叫value时，可以省略value不写 如:@VIP("xxx")
 * 	  2.如果注解定义中有多个方法，并且除了value以外的所有方法全部都默认值，
 * 		此时也可以在调用注解的时候，省去“value =”而直接对value进行赋值。
 * */
	String level() default "高级";
	int age() default 18;
	String[] hobby() default {"java","C","DOTA3","美女"} ;

}
